package com.neuedu.it.teach.service.impl;

import com.neuedu.it.teach.dao.HelpDao;
import com.neuedu.it.teach.dao.UserDao;
import com.neuedu.it.teach.entity.Help;
import com.neuedu.it.teach.entity.User;
import com.neuedu.it.teach.entity.StudentInfo;
import com.neuedu.it.teach.service.HelpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.neuedu.it.teach.dao.StudentInfoDao;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.util.*;

@Service
public class HelpServiceImpl implements HelpService {

    @Autowired
    private HelpDao helpDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private StudentInfoDao studentDao;

    @Override
    @Transactional
    public Help insertHelp(Help help) {
        int studentId = help.getStudentId();
        StudentInfo student = studentDao.selectStudentsByStudentId(studentId);
        if (student == null) {
            return null;
        }
        help.setReward((int) (Math.random() * 300 + 200));
        helpDao.insertHelp(help);
        return help;
    }

    @Override
    @Transactional
    public boolean updateHelp(Integer helpId, String status) {
        Help help = new Help();
        help.setHelpId(helpId);
        help.setStatus(status);
        return helpDao.updateHelp(help);
    }

    @Override
    @Transactional
    public boolean updateHelp(Help help) {
        return helpDao.updateHelp(help);
    }

    @Override
    @Transactional
    public Help deleteHelp(Help help) {
        helpDao.deleteHelp(help.getHelpId());
        return help;
    }

    @Override
    public Help queryHelp(Help help) {
        return helpDao.queryHelp(help);
    }

    @Override
    public List<Map<String, Object>> queryHelpByUserId(Help help) {
        int userId = help.getUserId();
        User user = userDao.queryUserById(userId);

        if (user != null && user.getIsTeacher()) {
            return Collections.emptyList();
        }

        List<Map<String, Object>> pendingHelps = helpDao.queryHelpByUserId(userId);
        if (pendingHelps != null && !pendingHelps.isEmpty()) {
            return processPendingHelps(pendingHelps);
        }
        return Collections.emptyList();
    }

    @Override
    public Map<String, Object> queryHelpByHelpId(Help help) {
        Map<String, Object> pendingHelp = helpDao.queryHelpByHelpId(help.getHelpId());
        if (pendingHelp != null) {
            return processPendingHelp(pendingHelp);
        }
        return null;
    }

    @Override
    public Help queryHelpByStatus(Help help) {
        return helpDao.queryHelpByStatus(help.getStatus());
    }

    @Override
    public List<Map<String, Object>> getPendingHelpByTitle(String title) {
        List<Map<String, Object>> pendingHelps = helpDao.getPendingHelpByTitle(title);
        System.out.println("pendingHelps: " + pendingHelps);
        return processPendingHelps(pendingHelps);
    }

    @Override
    public List<Map<String, Object>> getAllPendingHelp() {
        List<Map<String, Object>> pendingHelps = helpDao.getAllPendingHelp();
        System.out.println("pendingHelps: " + pendingHelps);
        return processPendingHelps(pendingHelps);
    }

    private List<Map<String, Object>> processPendingHelps(List<Map<String, Object>> pendingHelps) {
        if (pendingHelps == null || pendingHelps.isEmpty()) {
            return Collections.emptyList();
        }
        for (Map<String, Object> pendingHelp : pendingHelps) {
            processPendingHelp(pendingHelp);
        }
        return pendingHelps;
    }

    private Map<String, Object> processPendingHelp(Map<String, Object> pendingHelp) {
        if (pendingHelp == null) {
            return Collections.emptyMap();
        }

        // Convert keys to lowercase
        Map<String, Object> lowerCaseMap = new HashMap<>();
        for (String key : new HashSet<>(pendingHelp.keySet())) {
            Object value = pendingHelp.remove(key);
            lowerCaseMap.put(key.toLowerCase(), value);
        }
        pendingHelp.putAll(lowerCaseMap);

        // Process Clob description
        Object descriptionObj = pendingHelp.get("description");
        if (descriptionObj instanceof java.sql.Clob) {
            pendingHelp.put("description", clobToString(descriptionObj));
        }

        // Process birthdate to calculate age
        Object birthdateObj = pendingHelp.get("birthdate");
        if (birthdateObj != null) {
            try {
                if (birthdateObj instanceof java.sql.Date) {
                    java.sql.Date birthdate = (java.sql.Date) birthdateObj;
                    LocalDate birthLocalDate = convertToDate(birthdate).toInstant()
                            .atZone(ZoneId.systemDefault())
                            .toLocalDate();
                    int age = Period.between(birthLocalDate, LocalDate.now()).getYears();
                    pendingHelp.put("age", age);
                } else {
                    System.err.println("Unexpected type for 'birthdate': " + birthdateObj.getClass().getName());
                }
            } catch (Exception e) {
                System.err.println("Error processing birthdate: " + e.getMessage());
            }
        }
        return pendingHelp;
    }

    private String clobToString(Object clobObj) {
        if (clobObj instanceof java.sql.Clob) {
            try {
                java.sql.Clob clob = (java.sql.Clob) clobObj;
                return clob.getSubString(1, (int) clob.length());
            } catch (Exception e) {
                e.printStackTrace();
                return "ERROR_READING_CLOB";
            }
        } else {
            return clobObj != null ? clobObj.toString() : null;
        }
    }

    private java.util.Date convertToDate(java.sql.Date sqlDate) {
        return new java.util.Date(sqlDate.getTime());
    }
}
